<template>
  <div style="height: 100%;width: 100%">
    <div class="resp-panel">
      <h3 class="panel-title">
        <span class="title-accent"></span>
        3. 呼吸（RESP）监测
      </h3>

      <!-- 波形卡片 -->
      <div class="card chart-card">
        <div class="sub-title">
          呼吸波形（{{ totalSeconds }}秒片段）
          <span class="tag">可滚动</span>
        </div>
        <div ref="chartRef" class="chart"></div>
        <div class="tips">
          采样率：<b>{{ samplingRate }}</b> Hz（拖动/缩放查看细节；窗口默认展示 <b>{{ windowSeconds }}</b> 秒）
        </div>
      </div>

      <!-- 指标卡片 -->
      <div class="card metrics-card">
        <div class="metric">
          <div class="metric-label">平均呼吸频率</div>
          <div class="metric-value primary">{{ avgRate }}<span class="unit">次/分</span></div>
        </div>
        <div class="metric">
          <div class="metric-label">呼吸暂停次数</div>
          <div class="metric-value">{{ apneaCount }}<span class="unit">次</span></div>
        </div>
        <div class="metric">
          <div class="metric-label">最长暂停时长</div>
          <div class="metric-value">{{ longestApnea }}<span class="unit">秒</span></div>
        </div>
      </div>
    </div>
    <div class="container" >
      <div class="inner-container">
        <div class="section-header">
          <div class="title">分析意见</div>
          <el-button class="edit-button" @click="dynamicEdit">
            <font-awesome-icon :icon="['fas','fa-pencil-alt']" class="edit-icon"></font-awesome-icon>
            <el-text v-if="!editMode"  class="edit-text">编辑</el-text>
            <el-text v-if="editMode"  class="edit-text">保存</el-text>
          </el-button>
        </div>
        <div class="section-content">
          <div v-if="editMode" class="section-content-input">
            <el-input  type="textarea" class="input-area"  :rows="4" v-model="diagnosisData"></el-input>
          </div>
          <el-text v-else class="text-content">{{ diagnosisData }}</el-text>
        </div>
      </div>
    </div>
  </div>


</template>

<script setup lang="js">
import { ref, onMounted, onBeforeUnmount, watch, computed, nextTick } from 'vue'
import * as echarts from 'echarts'
import {FontAwesomeIcon} from "@fortawesome/vue-fontawesome";
import {getRespData} from "@/api/copd/copdReport.js";


/**
 * Props:
 * respSeries: 呼吸波形，长度应为 totalSeconds * samplingRate
 * samplingRate: 采样率，默认 125Hz
 * totalSeconds: 总时长（默认 30s）
 * windowSeconds: 初始显示窗口宽度，控制峰间间距观感（默认 8s）
 * peakMinDistanceSec: 峰之间的最小间隔（秒），用于估计呼吸频率（默认 1.5s）
 * apneaThreshold: 暂停阈值，|信号| 低于该值视为“无呼吸”（默认 0.08）
 * apneaMinSeconds: 暂停最短持续秒数（默认 10s）
 */
const props = defineProps({
  respSeries: {
    type: Array,
    default: () => {
      // —— 演示波：30s、125Hz，约 21 次/分，含两处短暂停 —— //
      const fs = 125
      const T = 30
      const N = fs * T
      const arr = new Array(N).fill(0)
      // 基本呼吸频率 ~0.35Hz（≈21次/分），叠加轻微噪声
      for (let i = 0; i < N; i++) {
        const t = i / fs
        const base = Math.sin(2 * Math.PI * 0.35 * t)
        const shape = base + 0.15 * Math.sin(2 * Math.PI * 0.7 * t + Math.PI / 3)
        const noise = (Math.random() - 0.5) * 0.05
        arr[i] = shape + noise
      }
      // 两段“暂停”（幅度压低），模拟 2 次暂停
      const low = (startSec, durSec) => {
        const s = Math.round(startSec * fs)
        const e = Math.min(N - 1, s + Math.round(durSec * fs))
        for (let i = s; i <= e; i++) arr[i] *= 0.02
      }
      low(8.5, 3)   // 8.5s 起 3s
      low(20.0, 3)  // 20s 起 3s
      return arr
    }
  },
  samplingRate: { type: Number, default: 125 },
  totalSeconds: { type: Number, default: 30 },
  windowSeconds: { type: Number, default: 8 },
  peakMinDistanceSec: { type: Number, default: 1.5 },
  apneaThreshold: { type: Number, default: 0.08 },
  apneaMinSeconds: { type: Number, default: 10 },
  currentReportId: Number, // 根据currentReportId的类型进行修改
  currentReport: Object
})
const respReportData = ref(null)

// 1) 兼容不同后端字段名：waveform / data / resp / samples（任选其一）
function normalizeRespSeries(d) {
  if (!d) return null
  if (Array.isArray(d)) return d
  const raw = d.waveform || d.data || d.resp || d.samples
  if (!raw) return null
  if (Array.isArray(raw)) {
    if (typeof raw[0] === 'number') return raw           // [y,y,y,...]
    if (typeof raw[0] === 'object') return raw.map(p => (p.v ?? p.y ?? 0)) // [{t,v}] 或 [{x,y}]
  }
  return null
}

// 2) 采样率优先取后端（常见字段：sampleRate 或 fs）
const samplingRateFromApi = computed(() => {
  const fs = respReportData.value?.sampleRate ?? respReportData.value?.fs
  return Number(fs) || props.samplingRate
})

// 3) 统一出口：最终使用的波形/采样率/总时长
const respSeriesFromApi = computed(() => normalizeRespSeries(respReportData.value))
const finalSeries  = computed(() => respSeriesFromApi.value ?? props.respSeries)
const finalFs      = computed(() => samplingRateFromApi.value)
const finalSeconds = computed(() => {
  const n = finalSeries.value?.length || 0
  return n ? (n / finalFs.value) : props.totalSeconds
})


const currentSeries = ref(props.respSeries)
const currentFs = ref(props.samplingRate)


/* ---------------- 指标估计（简化规则，方便替换后端真实值） ---------------- */
const avgRate = computed(() => {
  const fs = finalFs.value
  const minDist = Math.max(1, Math.round(props.peakMinDistanceSec * fs))
  const y = finalSeries.value || []
  const peaks = []
  let last = -minDist
  for (let i = 1; i < y.length - 1; i++) {
    if (y[i] > y[i - 1] && y[i] > y[i + 1] && y[i] > 0.15) {
      if (i - last >= minDist) { peaks.push(i); last = i }
    }
  }
  const breaths = peaks.length
  const minutes = finalSeconds.value / 60
  return Math.round((breaths / minutes) * 10) / 10
})

const apneaCount = computed(() => {
  const fs = finalFs.value
  const minLen = Math.round(props.apneaMinSeconds * fs)
  const thr = Math.abs(props.apneaThreshold)
  const y = finalSeries.value || []
  let count = 0, run = 0
  for (let i = 0; i < y.length; i++) {
    if (Math.abs(y[i]) < thr) { run++ }
    else { if (run >= minLen) count++; run = 0 }
  }
  if (run >= minLen) count++
  return count
})

const longestApnea = computed(() => {
  const fs = finalFs.value
  const thr = Math.abs(props.apneaThreshold)
  const y = finalSeries.value || []
  let maxRun = 0, run = 0
  for (let i = 0; i < y.length; i++) {
    if (Math.abs(y[i]) < thr) { run++; if (run > maxRun) maxRun = run }
    else run = 0
  }
  return Math.round((maxRun / fs) * 10) / 10
})


/* ---------------- ECharts ---------------- */
const chartRef = ref(null)
let chart = null
let ro = null

function buildOption () {
  const fs = finalFs.value
  const y  = finalSeries.value || []
  const x  = Array.from({ length: y.length }, (_, i) => (i / fs).toFixed(2))

  const maxAbs = Math.max(0.8, ...y.map(v => Math.abs(v)))
  const ymax = Math.ceil((maxAbs * 1.2) * 10) / 10

  const totalPoints = y.length
  const winPoints = Math.min(totalPoints, Math.round((props.windowSeconds || 8) * fs))
  const endPercent = totalPoints ? (winPoints / totalPoints) * 100 : 100

  return {
    grid: { left: 44, right: 16, top: 30, bottom: 36 },
    tooltip: {
      trigger: 'axis',
      axisPointer: { type: 'line' },
      formatter: (ps) => {
        if (!ps || !ps.length) return ''
        const p = ps[0]
        return `t=${p.axisValue}s<br/>Resp: ${Number(p.data).toFixed(3)}`
      }
    },
    xAxis: {
      type: 'category',
      boundaryGap: false,
      axisLine: { lineStyle: { color: '#D9D9D9' } },
      axisLabel: { color: '#8c8c8c' },
      data: x
    },
    yAxis: {
      type: 'value',
      axisLine: { show: false },
      axisTick: { show: false },
      splitLine: { lineStyle: { color: '#F0F0F0' } },
      min: -ymax,
      max: ymax
    },
    dataZoom: [
      { type: 'slider', height: 18, bottom: 6, start: 0, end: endPercent, brushSelect: false },
      { type: 'inside', zoomOnMouseWheel: true }
    ],
    series: [
      {
        type: 'line',
        name: 'RESP',
        smooth: true,
        symbol: 'none',
        data: y,
        lineStyle: { width: 2, color: '#35c44b' },
        areaStyle: {
          opacity: 0.18,
          color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
            { offset: 0, color: 'rgba(53,196,75,.30)' },
            { offset: 1, color: 'rgba(53,196,75,0)' }
          ])
        }
      }
    ]
  }
}



function renderChart () {
  if (!chartRef.value) return
  if (!chart) chart = echarts.init(chartRef.value)
  chart.setOption(buildOption(), true)
}

function handleResize () { chart && chart.resize() }

onMounted(() => {
  nextTick(renderChart)
  ro = new ResizeObserver(() => handleResize())
  if (chartRef.value && ro) ro.observe(chartRef.value)
  window.addEventListener('resize', handleResize)

  getRespData(props.currentReportId,props.currentReport.startTime).then((res) =>{
    if(res.data.code==200){

      respReportData.value=res.data.data

      currentSeries.value = Array.isArray(res.data.data) ? res.data.data : []

      // 更新图表
      renderChart()
    }

  })
})

onBeforeUnmount(() => {
  if (ro && chartRef.value) ro.unobserve(chartRef.value)
  window.removeEventListener('resize', handleResize)
  chart && chart.dispose()
  chart = null
})

// 数据变化时重绘
watch(
    () => [respReportData.value, finalFs.value, props.windowSeconds],
    () => renderChart(),
    { deep: true }
)


const editMode=ref(false)
const diagnosisData=ref("")
const dynamicEdit = (index)=>{
  editMode.value = !editMode.value
  if (editMode.value === false){
    // updateEvaluation()
  }
}
</script>

<style scoped lang="scss">
:root {
  --brand: #1890ff;
  --ok: #52c41a;
  --text-1: #262626;
  --text-2: #595959;
  --text-3: #8c8c8c;
  --card-bg: #fff;
  --card-border: #f0f0f0;
  --shadow: 0 6px 16px rgba(0,0,0,.06);
  --radius-lg: 14px;
}

.resp-panel {
  padding-top: 16px;
  width: 100%;
  box-sizing: border-box;
  //padding: 16px 18px 20px;
  color: var(--text-1);
  font-family: "Microsoft YaHei", system-ui, -apple-system, Segoe UI, Roboto, Arial, sans-serif;


  /* 标题 */
  .panel-title {
    display: flex;
    align-items: center;
    gap: 10px;
    margin: 0 0 12px;
    font-size: 18px;
    font-weight: 700;
  }
  .title-accent {
    width: 6px;
    height: 16px;
    background: var(--brand);
    border-radius: 3px;
  }

  /* 卡片通用 */
  .card {
    background: var(--card-bg);
    border: 1px solid var(--card-border);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow);
  }

  /* 波形卡片 */
  .chart-card { padding: 10px 12px 8px; }
  .sub-title {
    display: flex;
    align-items: center;
    gap: 8px;
    font-size: 13px;
    color: var(--text-3);
    padding: 6px 4px 0;
  }
  .tag {
    font-size: 12px;
    color: #8c8c8c;
    background: #f5f5f5;
    padding: 1px 8px;
    border-radius: 999px;
  }
  .chart { width: 100%; height: 240px; }
  .tips { text-align: right; font-size: 12px; color: var(--text-3); padding: 2px 4px 0 0; }

  /* 指标卡片 */
  .metrics-card {
    margin-top: 12px;
    padding: 12px;
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 12px;
  }
  .metric {
    background: #fafafa;
    border: 1px solid #f2f2f2;
    border-radius: 10px;
    padding: 12px 14px;
  }
  .metric-label { color: var(--text-2); font-size: 14px; margin-bottom: 6px; }
  .metric-value { font-size: 18px; font-weight: 700; color: var(--text-1); }
  .metric-value.primary { color: #eb2f96; } /* 与手机端示例一致的强调色 */
  .unit { margin-left: 4px; font-size: 12px; color: var(--text-3); }

  @media (max-width: 900px) {
    .metrics-card { grid-template-columns: 1fr; }
    .chart { height: 220px; }
  }

}


.container {
  box-sizing: border-box;
  //margin: 10px;
  margin-top: 18px;

  //width: 100%;
  min-height: 180px;
  background-color: #eff2f9;
  border-radius: 10px;
  .inner-container {
    position: relative;
    width: 100%;
    height: 100%;
    display: flex;
    flex-direction: column;

    .header {
      width: 100%;
      height: 5%;
      margin-top: 2%;
    }

    .title {
      width: 20%;
      font-size: 15px;
      font-weight: bold;
      height: 100%;
      margin-left: 20px;
      align-items: center;
      display: flex;
    }

    .section {
      width: 100%;
    }

    .section-title {
      font-size: 16px;
      margin-left: 5%;
      font-weight: bold;
    }

    .section-header {
      width: 100%;
      display: flex;
      margin-top: 20px;
      justify-content: center;
      align-items: center;
    }

    .edit-button {
      margin-left: auto;
      background-color: #eff2f9;
      border: none;
    }

    .edit-icon {
      color: #3dd986;
      margin-left: 10px;
      margin-right: 10px;
      width: 20px;
      height: 20px;
    }

    .edit-text {
      font-size: 17px;
      color: #3dd986;
    }

    .section-content {
      width: 100%;
      display: flex;
      align-items: center;
    }
    .section-content-input{
      width: 100%;
      display: flex;
      align-items: center;
      justify-content: center;
    }
    .input-area {
      height: 100%;
      width: 95%;
    }

    .text-content {
      font-size: 16px;
      margin-left: 5%;
    }

    .footer {
      position: absolute;
      bottom: 0;
      width: 100%;
      margin-bottom: 5vh;
    }
  }

}


</style>
